package com.directv.z8training.EMS.AOP;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.util.StopWatch;

public class TimingLoggingInterceptor implements MethodInterceptor {

	private final Log log = LogFactory.getLog(getClass());

	private long thresholdMs;
	private long warnThresholdMs;
	private long errorThresholdMs;

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO Auto-generated method stub
		StopWatch sw = new StopWatch();
		sw.start(invocation.getMethod().getName());
		Object returnValue = invocation.proceed();
		sw.stop();

		if (sw.getTotalTimeMillis() >= thresholdMs)
			logMethodCall(invocation, sw.getTotalTimeMillis());

		return returnValue;
	}

	private void logMethodCall(MethodInvocation invocation, long ms) {
		Method m = invocation.getMethod();
		Object target = invocation.getThis();

		StringBuffer msg = new StringBuffer();
		msg.append("TIMER - Executed Method: ");
		msg.append(target.getClass().getName());
		msg.append('.');
		msg.append(m.getName());
		msg.append(" in (ms): ");
		msg.append(ms);
		if (ms > errorThresholdMs)
			log.error(msg);
		else if (ms > warnThresholdMs)
			log.warn(msg);
		else
			log.info(msg);
	}
	
	@Required
    public void setThresholdMs( long thresholdMs )
    {
        this.thresholdMs = thresholdMs;
    }

    @Required
    public void setWarnThresholdMs( long warnThresholdMs )
    {
        this.warnThresholdMs = warnThresholdMs;
    }

    @Required
    public void setErrorThresholdMs( long errorThresholdMs )
    {
        this.errorThresholdMs = errorThresholdMs;
    }

}
